home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / progtool / pascal / o_gem / units / ovalidat.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-09-22  |  16.4 KB  |  667 lines

  1. {**************************************
  2.  *  O b j e c t G E M   Version 1.17  *
  3.  *  Copyright 1992-94 by Thomas Much  *
  4.  **************************************
  5.  *       Unit  O V A L I D A T        *
  6.  **************************************
  7.  *    Softdesign Computer Software    *
  8.  *    Thomas Much, Gerwigstraße 46,   *
  9.  *  76131 Karlsruhe, (0721) 62 28 41  *
  10.  *         Thomas Much @ KA2          *
  11.  *  UK48@ibm3090.rz.uni-karlsruhe.de  *
  12.  **************************************
  13.  *    erstellt am:        13.07.1992  *
  14.  *    letztes Update am:  22.06.1994  *
  15.  **************************************}
  16.  
  17. {
  18.   WICHTIGE ANMERKUNGEN ZUM QUELLTEXT:
  19.  
  20.   ObjectGEM wird mit dem _vollständigen_ Quelltext ausgeliefert, d.h.
  21.   jeder kann sich die Unit selbst compilieren, womit die extrem lästigen
  22.   Kompatibilitätsprobleme mit den PP-Releases beseitigt sind.
  23.   ObjectGEM ist und bleibt aber trotzdem SHAREWARE, d.h. wer die Biblio-
  24.   thek regelmäßig benutzt, muß sich REGISTRIEREN lassen. Dafür gibt es
  25.   die neueste Version und - gegen einen geringen Aufpreis - auch ein
  26.   gedrucktes Handbuch.
  27.  
  28.   WICHTIG: Wer den Quelltext verändert und dann Probleme beim Compilieren,
  29.   Ausführen o.ä. hat, kann nicht damit rechnen, daß ich den Fehler suche;
  30.   tritt der Fehler allerdings auch mit dem Original-Quelltext auf, würde
  31.   ich mich über eine genaue Fehlerbeschreibung freuen. Veränderte Quell-
  32.   texte dürfen _nicht_ weitergegeben werden, dies wäre ein Verstoß gegen
  33.   das Copyright!
  34.  
  35.   Wer beim Durchstöbern des Textes auf vermeintliche Fehler oder verbesse-
  36.   rungswürdige Stellen trifft (von letzterem gibt es sicherlich noch viele),
  37.   kann mir dies gerne mitteilen - ich habe auch ich nichts gegen kostenlos
  38.   zur Verfügung gestellte optimierte Routinen (sofern sich jemand die Mühe
  39.   macht). Wer in anderen Projekten, die nicht in direkter Konkurrenz zu
  40.   ObjectGEM stehen, einzelne Routinen verwenden möchte, wendet sich bitte
  41.   an mich (ein solcher Austausch sollte kein Problem sein).
  42.  
  43.   Wer sich auf nicht dokumentierte "implementation"- oder "private"-Eigen-
  44.   schaften verläßt, darf sich nicht über Inkompatibilitäten zu späteren
  45.   Versionen wundern; wer meint, eine Dokumentationslücke entdeckt zu haben,
  46.   kann mir dies gerne mitteilen.
  47.  
  48.   Kleine Info zum Schluß: Als "default tabsize" verwende ich 2. Wer drei
  49.   Punkte ("...") im Quelltext entdeckt, hat eine Stelle gefunden, an der
  50.   ich z.Z. arbeite ;-)
  51.  
  52.   "Möge die OOP mit Euch sein!"
  53. }
  54.  
  55.  
  56. {$IFDEF DEBUG}
  57.     {$B+,D+,G-,I-,L+,N-,P-,Q+,R+,S+,T-,V-,X+,Z+}
  58. {$ELSE}
  59.     {$B+,D-,G-,I-,L-,N-,P-,Q-,R-,S-,T-,V-,X+,Z+}
  60. {$ENDIF}
  61.  
  62. unit OValidat;
  63.  
  64. interface
  65.  
  66. uses
  67.  
  68.     Objects,OTypes,OWindows;
  69.  
  70. type
  71.  
  72.     PFilterValidator       = ^TFilterValidator;
  73.     TFilterValidator       = object(TValidator)
  74.         public
  75.         ValidChars: TCharSet;
  76.         constructor Init(ValidCharSet: TCharSet);
  77.         procedure Error; virtual;
  78.         function IsValid(s: string): boolean; virtual;
  79.         function IsValidInput(var s: string; SuppressFill: boolean): boolean; virtual;
  80.     end;
  81.  
  82.     PRangeValidator        = ^TRangeValidator;
  83.     TRangeValidator        = object(TFilterValidator)
  84.         public
  85.         Min,
  86.         Max: longint;
  87.         constructor Init(AMin,AMax: longint);
  88.         procedure Error; virtual;
  89.         function IsValid(s: string): boolean; virtual;
  90.         function IsValidInput(var s: string; SuppressFill: boolean): boolean; virtual;
  91.     end;
  92.  
  93.     PLookupValidator       = ^TLookupValidator;
  94.     TLookupValidator       = object(TValidator)
  95.         public
  96.         function IsValid(s: string): boolean; virtual;
  97.         function Lookup(s: string): boolean; virtual;
  98.     end;
  99.  
  100.     PStringLookupValidator = ^TStringLookupValidator;
  101.     TStringLookupValidator = object(TLookupValidator)
  102.         public
  103.         Strings: PStringCollection;
  104.         constructor Init(AString: PStringCollection);
  105.         destructor Done; virtual;
  106.         procedure Error; virtual;
  107.         function Lookup(s: string): boolean; virtual;
  108.         procedure NewStringList(AString: PStringCollection); virtual;
  109.     end;
  110.  
  111.     PPXPictureValidator    = ^TPXPictureValidator;
  112.     TPXPictureValidator    = object(TValidator)
  113.         public
  114.         Pic: PString;
  115.         constructor Init(APic: string; AutoFill: boolean);
  116.         destructor Done; virtual;
  117.         procedure Error; virtual;
  118.         function IsValid(s: string): boolean; virtual;
  119.         function IsValidInput(var s: string; SuppressFill: boolean): boolean; virtual;
  120.         function Picture(var Input: string; AutoFill: boolean): TPicResult; virtual;
  121.     end;
  122.  
  123.  
  124.  
  125. implementation
  126.  
  127. uses
  128.  
  129.     OProcs;
  130.  
  131.  
  132. { *** Objekt TFILTERVALIDATOR *** }
  133.  
  134. constructor TFilterValidator.Init(ValidCharSet: TCharSet);
  135.  
  136.     begin
  137.         if not(inherited Init) then fail;
  138.         Options:=voOnEdit;
  139.         ValidChars:=ValidCharSet
  140.     end;
  141.  
  142.  
  143. procedure TFilterValidator.Error;
  144.  
  145.     begin
  146.         if Application<>nil then
  147.             with Application^ do
  148.                 begin
  149.                     if (Attr.Country=FRG) or (Attr.Country=SWG) then
  150.                         Alert(Window,1,NOTE,'Die Eingabe enthält ungültige Zeichen.','  &OK  ')
  151.                     else
  152.                         Alert(Window,1,NOTE,'Invalid characters in input.','  &OK  ')
  153.                 end
  154.     end;
  155.  
  156.  
  157. function TFilterValidator.IsValid(s: string): boolean;
  158.     var q  : integer;
  159.         vld: boolean;
  160.  
  161.     begin
  162.         vld:=inherited IsValid(s);
  163.         if vld then
  164.             for q:=1 to length(s) do
  165.                 if not(s[q] in ValidChars) then vld:=false;
  166.         IsValid:=vld
  167.     end;
  168.  
  169.  
  170. function TFilterValidator.IsValidInput(var s: string; SuppressFill: boolean): boolean;
  171.     var q: integer;
  172.  
  173.     begin
  174.         IsValidInput:=true;
  175.         if length(s)>0 then
  176.             for q:=1 to length(s) do
  177.                 if not(s[q] in ValidChars) then
  178.                     begin
  179.                         if upcase(s[q]) in ValidChars then s[q]:=upcase(s[q])
  180.                         else
  181.                             IsValidInput:=false
  182.                     end
  183.     end;
  184.  
  185. { *** TFILTERVALIDATOR *** }
  186.  
  187.  
  188.  
  189. { *** Objekt TRANGEVALIDATOR *** }
  190.  
  191. constructor TRangeValidator.Init(AMin,AMax: longint);
  192.  
  193.     begin
  194.         if not(inherited Init(['0'..'9','+','-'])) then fail;
  195.         Options:=Options and not(voOnEdit);
  196.         Min:=AMin;
  197.         Max:=AMax;
  198.         if Min>=0 then ValidChars:=ValidChars-['-']
  199.     end;
  200.  
  201.  
  202. procedure TRangeValidator.Error;
  203.  
  204.     begin
  205.         if Application<>nil then
  206.             with Application^ do
  207.                 begin
  208.                     if (Attr.Country=FRG) or (Attr.Country=SWG) then
  209.                         Alert(Window,1,NOTE,' Wert ist nicht im Bereich | von '+ltoa(Min)+' bis '+ltoa(Max)+'.','  &OK  ')
  210.                     else
  211.                         Alert(Window,1,NOTE,' Value is not in the range | '+ltoa(Min)+' to '+ltoa(Max)+'.','  &OK  ')
  212.             end
  213.     end;
  214.  
  215.  
  216. function TRangeValidator.IsValid(s: string): boolean;
  217.     var value: longint;
  218.  
  219.     begin
  220.         StrPTrim(s);
  221.         if inherited IsValid(s) then
  222.             begin
  223.                 value:=atol(s);
  224.                 IsValid:=(value>=Min) and (value<=Max)
  225.             end
  226.         else
  227.             IsValid:=false
  228.     end;
  229.  
  230.  
  231. function TRangeValidator.IsValidInput(var s: string; SuppressFill: boolean): boolean;
  232.     var value: longint;
  233.  
  234.     begin
  235.         if inherited IsValidInput(s,SuppressFill) then
  236.             begin
  237.                 value:=atol(s);
  238.                 IsValidInput:=(value>=Min) and (value<=Max)
  239.             end
  240.         else
  241.             IsValidInput:=false
  242.     end;
  243.  
  244. { *** TRANGEVALIDATOR *** }
  245.  
  246.  
  247.  
  248. { *** Objekt TLOOKUPVALIDATOR *** }
  249.  
  250. function TLookupValidator.IsValid(s: string): boolean;
  251.     var vald: boolean;
  252.  
  253.     begin
  254.         vald:=Lookup(s);
  255.         if vald then
  256.             if bTst(Options,voNotEmpty) then
  257.                 vald:=length(s)>0;
  258.         IsValid:=vald
  259.     end;
  260.  
  261.  
  262. function TLookupValidator.Lookup(s: string): boolean;
  263.  
  264.     begin
  265.         Lookup:=true
  266.     end;
  267.  
  268. { *** TLOOKUPVALIDATOR *** }
  269.  
  270.  
  271.  
  272. { *** Objekt TSTRINGLOOKUPVALIDATOR *** }
  273.  
  274. constructor TStringLookupValidator.Init(AString: PStringCollection);
  275.  
  276.     begin
  277.         if not(inherited Init) then fail;
  278.         Strings:=AString
  279.     end;
  280.  
  281.  
  282. destructor TStringLookupValidator.Done;
  283.  
  284.     begin
  285.         NewStringList(nil);
  286.         inherited Done
  287.     end;
  288.  
  289.  
  290. procedure TStringLookupValidator.Error;
  291.  
  292.     begin
  293.         if Application<>nil then
  294.             with Application^ do
  295.                 begin
  296.                     if (Attr.Country=FRG) or (Attr.Country=SWG) then
  297.                         Alert(Window,1,NOTE,'Die Eingabe ist nicht gültig.','  &OK  ')
  298.                     else
  299.                         Alert(Window,1,NOTE,'Input not in valid-list.','  &OK  ')
  300.             end
  301.     end;
  302.  
  303.  
  304. function TStringLookupValidator.Lookup(s: string): boolean;
  305.     var dummy: longint;
  306.  
  307.     begin
  308.         if Strings<>nil then Lookup:=Strings^.Search(@s,dummy)
  309.         else
  310.             Lookup:=false
  311.     end;
  312.  
  313.  
  314. procedure TStringLookupValidator.NewStringList(AString: PStringCollection);
  315.  
  316.     begin
  317.         if Strings<>nil then Dispose(Strings,Done);
  318.         Strings:=AString
  319.     end;
  320.  
  321. { *** TSTRINGLOOKUPVALIDATOR *** }
  322.  
  323.  
  324.  
  325. { *** Objekt TPXPICTUREVALIDATOR *** }
  326.  
  327. constructor TPXPictureValidator.Init(APic: string; AutoFill: boolean);
  328.     var dummy: string;
  329.  
  330.     begin
  331.         inherited Init;
  332.         Pic:=NewStr(APic);
  333.         Options:=voOnAppend;
  334.         if AutoFill then Options:=Options or voFill;
  335.         dummy:='';
  336.         if Picture(dummy,false)<>prEmpty then Status:=vsSyntax
  337.     end;
  338.  
  339.  
  340. destructor TPXPictureValidator.Done;
  341.  
  342.     begin
  343.         DisposeStr(Pic);
  344.         inherited Done
  345.     end;
  346.  
  347.  
  348. procedure TPXPictureValidator.Error;
  349.  
  350.     begin
  351.         if Application<>nil then
  352.             with Application^ do
  353.                 begin
  354.                     if (Attr.Country=FRG) or (Attr.Country=SWG) then
  355.                         Alert(Window,1,NOTE,'Die Eingabe paßt nicht auf|'+Pic^,'  &OK  ')
  356.                     else
  357.                         Alert(Window,1,NOTE,'Input does not conform to|'+Pic^,'  &OK  ')
  358.             end
  359.     end;
  360.  
  361.  
  362. function TPXPictureValidator.IsValid(s: string): boolean;
  363.     var res: TPicResult;
  364.  
  365.     begin
  366.         res:=Picture(s,false);
  367.         if bTst(Options,voNotEmpty) and ((res=prEmpty) or (length(s)=0)) then
  368.             begin
  369.                 IsValid:=false;
  370.                 exit
  371.             end;
  372.         IsValid:=(Pic=nil) or (res=prComplete) or (res=prEmpty)
  373.     end;
  374.  
  375.  
  376. function TPXPictureValidator.IsValidInput(var s: string; SuppressFill: boolean): boolean;
  377.  
  378.     begin
  379.         IsValidInput:=(Pic=nil) or (Picture(s,bTst(Options,voFill) and not(SuppressFill))<>prError)
  380.     end;
  381.  
  382.  
  383. function TPXPictureValidator.Picture(var Input: string; AutoFill: boolean): TPicResult;
  384.     const special: set of char = [';','*','[',']','{','}',','];
  385.  
  386.     var q,k1,k2,mip: integer;
  387.         outp       : string;
  388.         ret        : TPicResult;
  389.  
  390.     function check(inpt,mask: string; var out: string): TPicResult;
  391.         label _getph;
  392.  
  393.         var ph,aus             : string;
  394.             c,d,ip,mp,bis,letzt: integer;
  395.             gueltig            : boolean;
  396.             cnt                : longint;
  397.             r                  : TPicResult;
  398.  
  399.         begin
  400.             { Ausfüllen verhindern + AutoFill beachten... }
  401.             k2:=0;
  402.             c:=1;
  403.             while c<=length(mask) do
  404.                 begin
  405.                     case mask[c] of
  406.                         ';': inc(c);
  407.                         '[': inc(k2);
  408.                         ']': dec(k2)
  409.                     end;
  410.                     inc(c)
  411.                 end;
  412.             if k2<>0 then
  413.                 begin
  414.                     check:=prSyntax;
  415.                     exit
  416.                 end
  417.             else
  418.                 check:=prIncomplete;
  419.             aus:=out;
  420.             mp:=1;
  421.             ip:=1;
  422.             while mp<=length(mask) do
  423.                 begin
  424.                     case mask[mp] of
  425.                         '}',']': begin
  426.                                              check:=prAmbiguous;
  427.                                              exit
  428.                                      end;
  429.                         ',': begin
  430.                                      check:=prSyntax;
  431.                                      exit
  432.                              end;
  433.                         ';': begin
  434.                                      ph:=mask[mp+1];
  435.                                      inc(mp,2);
  436.                                      goto _getph
  437.                                  end;
  438.                         '*': begin
  439.                                c:=mp+1;
  440.                                cnt:=0;
  441.                                while mask[c] in ['0'..'9'] do
  442.                                  begin
  443.                                    cnt:=cnt*10+ord(mask[c])-48;
  444.                                    inc(c)
  445.                                  end;
  446.                                mp:=c;
  447.                                inc(c);
  448.                                letzt:=mp;
  449.                                case mask[mp] of
  450.                                  '[': begin
  451.                                         check:=prSyntax;
  452.                                         exit
  453.                                       end;
  454.                                  '{': begin
  455.                                         bis:=1;
  456.                                                         while bis>0 do
  457.                                                             begin
  458.                                                                 case mask[c] of
  459.                                                                   ';': inc(c);
  460.                                                                     '{': inc(bis);
  461.                                                                     '}': dec(bis)
  462.                                                                 end;
  463.                                                                 inc(c)
  464.                                                             end;
  465.                                                         letzt:=c-1
  466.                                                     end
  467.                                end;
  468.                                if (letzt=mp) or (letzt-mp>1) then
  469.                                  begin
  470.                                        if cnt=0 then
  471.                                          repeat
  472.                                                      r:=check(StrPRight(inpt,length(inpt)+1-ip),copy(mask,mp,letzt+1-mp),aus);
  473.                                                      if r=prComplete then inc(ip,mip-1)
  474.                                          until r<>prComplete
  475.                                        else
  476.                                          for d:=1 to cnt do
  477.                                                      if check(StrPRight(inpt,length(inpt)+1-ip),copy(mask,mp,letzt+1-mp),aus)=prComplete then
  478.                                                        inc(ip,mip-1)
  479.                                            else
  480.                                              begin
  481.                                                check:=prError;
  482.                                                exit
  483.                                                  end
  484.                                    end;
  485.                                      mp:=c
  486.                                  end;
  487.                         '[': begin
  488.                                      c:=mp+1;
  489.                                      bis:=1;
  490.                                      while bis>0 do
  491.                                          begin
  492.                                              case mask[c] of
  493.                                                ';': inc(c);
  494.                                                  '[': inc(bis);
  495.                                                  ']': dec(bis)
  496.                                              end;
  497.                                              inc(c)
  498.                                          end;
  499.                                      if c-mp>2 then
  500.                                          if check(StrPRight(inpt,length(inpt)+1-ip),copy(mask,mp+1,c-mp-2),aus)=prComplete then
  501.                                            inc(ip,mip-1);
  502.                                      mp:=c
  503.                              end;
  504.                         '{': begin
  505.                                      c:=mp+1;
  506.                                      bis:=1;
  507.                                      while bis>0 do
  508.                                          begin
  509.                                              case mask[c] of
  510.                                                ';': inc(c);
  511.                                                  '{': inc(bis);
  512.                                                  '}': dec(bis)
  513.                                              end;
  514.                                              inc(c)
  515.                                          end;
  516.                                      d:=mp+1;
  517.                                      letzt:=d;
  518.                                      bis:=1;
  519.                                      gueltig:=false;
  520.                                      while (bis>0) and not(gueltig) do
  521.                                        begin
  522.                                              case mask[d] of
  523.                                                ';': inc(d);
  524.                                                  '{': inc(bis);
  525.                                                  '}': dec(bis);
  526.                                                  ',': if bis=1 then
  527.                                                         if d-letzt>0 then
  528.                                                             begin
  529.                                                               if check(StrPRight(inpt,length(inpt)+1-ip),copy(mask,letzt,d-letzt),aus)=prComplete then
  530.                                                                 begin
  531.                                                                     inc(ip,mip-1);
  532.                                                                   gueltig:=true
  533.                                                                 end;
  534.                                                               letzt:=d+1
  535.                                                             end
  536.                                              end;
  537.                                              inc(d)
  538.                                        end;
  539.                                      if not(gueltig) then
  540.                                          if d-letzt>1 then
  541.                                          begin
  542.                                                  if check(StrPRight(inpt,length(inpt)+1-ip),copy(mask,letzt,d-letzt-1),aus)=prComplete then
  543.                                                    inc(ip,mip-1)
  544.                                        else
  545.                                          begin
  546.                                            check:=prError;
  547.                                            exit
  548.                                              end
  549.                                          end;
  550.                                      mp:=c
  551.                              end
  552.                     else
  553.                         begin
  554.                             ph:='';
  555.                             _getph:
  556.                             while not(mask[mp] in special) and (mp<=length(mask)) do
  557.                                 begin
  558.                                     ph:=ph+mask[mp];
  559.                                     inc(mp)
  560.                                 end;
  561.                             if length(inpt)+1-ip<length(ph) then bis:=length(inpt)-ip
  562.                             else
  563.                                 bis:=length(ph)-1;
  564.                             for c:=0 to bis do
  565.                                 begin
  566.                                     case ph[c+1] of
  567.                                         '#': if not(inpt[ip+c] in ['0'..'9']) then
  568.                                                    begin
  569.                                                          check:=prError;
  570.                                                          exit
  571.                                                    end
  572.                                                  else
  573.                                                      aus:=aus+inpt[ip+c];
  574.                                         '?': if not(UpChar(inpt[ip+c]) in ['A'..'Z','Ä','Ö','Ü']) then
  575.                                                      begin
  576.                                                          check:=prError;
  577.                                                          exit
  578.                                                      end
  579.                                                  else
  580.                                                      aus:=aus+inpt[ip+c];
  581.                                         '&': if not(UpChar(inpt[ip+c]) in ['A'..'Z','Ä','Ö','Ü']) then
  582.                                                      begin
  583.                                                          check:=prError;
  584.                                                          exit
  585.                                                      end
  586.                                                  else
  587.                                                      aus:=aus+UpChar(inpt[ip+c]);
  588.                                         '@': aus:=aus+inpt[ip+c];
  589.                                         '!': aus:=aus+UpChar(inpt[ip+c])
  590.                                     else
  591.                                         begin
  592.                                             if UpChar(ph[c+1])=UpChar(inpt[ip+c]) then aus:=aus+ph[c+1]
  593.                                             else
  594.                                                 begin
  595.                                                     check:=prError;
  596.                                                     exit
  597.                                                 end
  598.                                         end
  599.                                     end
  600.                                 end;
  601.                             if bis<length(ph)-1 then exit;
  602.                             inc(ip,bis+1)
  603.                         end
  604.                     end
  605.                 end;
  606.             mip:=ip;
  607.             out:=aus;
  608.             check:=prComplete
  609.         end;
  610.  
  611.     begin
  612.         if Pic=nil then
  613.             begin
  614.                 Picture:=prError;
  615.                 exit
  616.             end;
  617.         Picture:=prSyntax;
  618.         q:=length(Pic^);
  619.         if (q=0) or (q>253) then exit;
  620.         k1:=0;
  621.         while (Pic^[q]=';') and (q>0) do
  622.             begin
  623.                 inc(k1);
  624.                 dec(q)
  625.             end;
  626.         if odd(k1) then exit;
  627.         if StrPRight(Pic^,1)='*' then
  628.             begin
  629.                 q:=length(pic^)-1;
  630.                 k1:=0;
  631.                 while (Pic^[q]=';') and (q>0) do
  632.                     begin
  633.                         inc(k1);
  634.                         dec(q)
  635.                     end;
  636.                 if not(odd(k1)) then exit
  637.             end;
  638.         q:=1;
  639.         k1:=0;
  640.         k2:=0;
  641.         while q<=length(Pic^) do
  642.             begin
  643.                 case Pic^[q] of
  644.                     ';': inc(q);
  645.                     '{': inc(k1);
  646.                     '}': dec(k1);
  647.                     '[': inc(k2);
  648.                     ']': dec(k2)
  649.                 end;
  650.                 inc(q)
  651.             end;
  652.         if (k1<>0) or (k2<>0) then exit;
  653.         if length(Input)=0 then
  654.             begin
  655.                 Picture:=prEmpty;
  656.                 exit
  657.             end;
  658.         outp:='';
  659.         ret:=check(Input,'{'+Pic^+'}',outp);
  660.         if mip<=length(Input) then ret:=prAmbiguous;
  661.         if (ret=prComplete) or (ret=prIncomplete) then Input:=outp;
  662.         Picture:=ret
  663.     end;
  664.  
  665. { *** Objekt TPXPICTUREVALIDATOR *** }
  666.  
  667. end.